<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { translate } from '../../plugins/i18n.plugin';
import {
	generatePassword,
	evaluatePasswordStrength,
	generatePasswordSuggestions,
	PRESET_SYMBOL_GROUPS,
	type PasswordOptions,
	type PasswordStrength
} from './password-generator.service';

// 密码选项
const passwordOptions = ref<PasswordOptions>({
	length: 16,
	includeUppercase: true,
	includeLowercase: true,
	includeNumbers: true,
	includeSymbols: true,
	excludeSimilar: false,
	excludeAmbiguous: false,
	customSymbols: '!@#$%^&*.,;:?!'
});

// 生成的密码
const generatedPassword = ref<string>('');
const passwordStrength = ref<PasswordStrength | null>(null);
const showPassword = ref<boolean>(false);
const copySuccess = ref<boolean>(false);

// 密码建议
const suggestions = ref<string[]>(generatePasswordSuggestions());

// 生成密码
const generateNewPassword = () => {
	generatedPassword.value = generatePassword(passwordOptions.value);
	passwordStrength.value = evaluatePasswordStrength(
		generatedPassword.value,
		passwordOptions.value.customSymbols
	);
};

// 复制密码
const copyPassword = async () => {
	if (generatedPassword.value) {
		try {
			await navigator.clipboard.writeText(generatedPassword.value);
			copySuccess.value = true;
			setTimeout(() => {
				copySuccess.value = false;
			}, 2000);
		} catch (error) {
			console.error('复制失败:', error);
		}
	}
};

// 密码强度颜色
const getStrengthColor = (level: string) => {
	switch (level) {
		case 'weak':
			return 'text-red-600';
		case 'medium':
			return 'text-yellow-600';
		case 'strong':
			return 'text-blue-600';
		case 'very-strong':
			return 'text-green-600';
		default:
			return 'text-gray-600';
	}
};

const getStrengthBgColor = (level: string) => {
	switch (level) {
		case 'weak':
			return 'bg-red-100';
		case 'medium':
			return 'bg-yellow-100';
		case 'strong':
			return 'bg-blue-100';
		case 'very-strong':
			return 'bg-green-100';
		default:
			return 'bg-gray-100';
	}
};

// 计算字符集大小
const charsetSize = computed(() => {
	let size = 0;
	if (passwordOptions.value.includeUppercase) size += 26;
	if (passwordOptions.value.includeLowercase) size += 26;
	if (passwordOptions.value.includeNumbers) size += 10;
	if (passwordOptions.value.includeSymbols) {
		// 使用自定义特殊字符的数量，如果没有则使用默认的32个
		const symbolCount = passwordOptions.value.customSymbols.trim()
			? passwordOptions.value.customSymbols.length
			: 32;
		size += symbolCount;
	}

	if (passwordOptions.value.excludeSimilar) {
		size -= 7; // 排除相似字符
	}
	if (passwordOptions.value.excludeAmbiguous) {
		size -= 16; // 排除易混淆字符
	}

	return Math.max(size, 1);
});

// 计算密码熵
const passwordEntropy = computed(() => {
	if (!generatedPassword.value) return 0;
	return Math.log2(Math.pow(charsetSize.value, passwordOptions.value.length));
});

// 监听选项变化，自动生成新密码
watch(
	passwordOptions,
	() => {
		if (generatedPassword.value) {
			generateNewPassword();
		}
	},
	{ deep: true }
);

// 添加特殊字符到自定义字符集
const addSymbols = (symbols: string) => {
	const currentSymbols = passwordOptions.value.customSymbols;
	const newSymbols = symbols
		.split('')
		.filter((char) => !currentSymbols.includes(char))
		.join('');
	passwordOptions.value.customSymbols = currentSymbols + newSymbols;
};

// 获取字符组名称
const getSymbolGroupName = (key: string) => {
	return translate(`tools.password-generator.symbolGroups.${key}`);
};

// 清空自定义特殊字符
const clearCustomSymbols = () => {
	passwordOptions.value.customSymbols = '';
};

// 使用默认字符集
const useDefaultSymbols = () => {
	passwordOptions.value.customSymbols = '';
};

// 初始化生成密码
generateNewPassword();
</script>

<template>
	<c-card>
		<div space-y-6>
			<!-- 生成的密码 -->
			<div>
				<h3 text-lg font-semibold mb-4>生成的密码</h3>
				<div bg-gray-50 p-4 rounded-lg border border-gray-200>
					<div flex items-center justify-between>
						<div flex-1>
							<div
								v-if="showPassword"
								text-xl
								font-mono
								text-gray-800>
								{{ generatedPassword }}
							</div>
							<div v-else text-xl font-mono text-gray-800>
								{{ '•'.repeat(generatedPassword.length) }}
							</div>
						</div>
						<div flex items-center gap-2>
							<c-button
								size="small"
								@click="showPassword = !showPassword"
								:type="showPassword ? 'primary' : 'default'">
								{{ showPassword ? '隐藏' : '显示' }}
							</c-button>
							<c-button
								size="small"
								@click="copyPassword"
								:type="copySuccess ? 'success' : 'primary'">
								{{ copySuccess ? '已复制' : '复制' }}
							</c-button>
							<c-button
								size="small"
								@click="generateNewPassword"
								type="primary">
								重新生成
							</c-button>
						</div>
					</div>
				</div>
			</div>

			<!-- 密码强度 -->
			<div v-if="passwordStrength">
				<h3 text-lg font-semibold mb-4>密码强度</h3>
				<div space-y-3>
					<!-- 强度条 -->
					<div>
						<div flex items-center justify-between mb-2>
							<span text-sm text-gray-600>强度评分</span>
							<span
								text-sm
								font-medium
								:class="
									getStrengthColor(passwordStrength.level)
								">
								{{ passwordStrength.score }}/100
							</span>
						</div>
						<div bg-gray-200 rounded-full h-2 overflow-hidden>
							<div
								:class="
									getStrengthBgColor(passwordStrength.level)
								"
								:style="{ width: passwordStrength.score + '%' }"
								h-full
								transition-all
								duration-300></div>
						</div>
					</div>

					<!-- 强度等级 -->
					<div flex items-center gap-2>
						<span text-sm text-gray-600>强度等级：</span>
						<span
							:class="getStrengthColor(passwordStrength.level)"
							text-sm
							font-medium
							capitalize>
							{{
								passwordStrength.level === 'very-strong'
									? '非常强'
									: passwordStrength.level === 'strong'
									? '强'
									: passwordStrength.level === 'medium'
									? '中等'
									: '弱'
							}}
						</span>
					</div>

					<!-- 密码熵 -->
					<div flex items-center gap-2>
						<span text-sm text-gray-600>密码熵：</span>
						<span text-sm font-medium text-blue-600>
							{{ passwordEntropy.toFixed(1) }} bits
						</span>
					</div>

					<!-- 反馈建议 -->
					<div v-if="passwordStrength.feedback.length > 0">
						<div text-sm text-gray-600 mb-2>改进建议：</div>
						<div space-y-1>
							<div
								v-for="feedback in passwordStrength.feedback"
								:key="feedback"
								text-sm
								text-orange-600
								flex
								items-center
								gap-1>
								<span>•</span>
								<span>{{ feedback }}</span>
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- 密码选项 -->
			<div>
				<h3 text-lg font-semibold mb-4>密码选项</h3>
				<div space-y-4>
					<!-- 密码长度 -->
					<div>
						<div flex items-center justify-between mb-2>
							<c-label>密码长度</c-label>
							<span text-sm text-gray-600>
								{{ passwordOptions.length }} 位
							</span>
						</div>
						<input
							v-model="passwordOptions.length"
							type="range"
							min="4"
							max="64"
							class="w-full"
							style="accent-color: #3b82f6" />
						<div flex justify-between text-xs text-gray-500 mt-1>
							<span>4</span>
							<span>8</span>
							<span>12</span>
							<span>16</span>
							<span>20</span>
							<span>32</span>
							<span>64</span>
						</div>
					</div>

					<!-- 字符类型 -->
					<div>
						<c-label>字符类型</c-label>
						<div grid grid-cols-1 md:grid-cols-2 gap-3 mt-2>
							<label flex items-center gap-2 cursor-pointer>
								<input
									v-model="passwordOptions.includeUppercase"
									type="checkbox"
									class="rounded" />
								<span text-sm>大写字母 (A-Z)</span>
							</label>
							<label flex items-center gap-2 cursor-pointer>
								<input
									v-model="passwordOptions.includeLowercase"
									type="checkbox"
									class="rounded" />
								<span text-sm>小写字母 (a-z)</span>
							</label>
							<label flex items-center gap-2 cursor-pointer>
								<input
									v-model="passwordOptions.includeNumbers"
									type="checkbox"
									class="rounded" />
								<span text-sm>数字 (0-9)</span>
							</label>
							<label flex items-center gap-2 cursor-pointer>
								<input
									v-model="passwordOptions.includeSymbols"
									type="checkbox"
									class="rounded" />
								<span text-sm>特殊字符</span>
							</label>
						</div>
					</div>

					<!-- 特殊字符选择 -->
					<div v-if="passwordOptions.includeSymbols">
						<c-label>特殊字符选择</c-label>
						<div space-y-4 mt-2>
							<!-- 预设字符组 -->
							<div>
								<div text-sm text-gray-600 mb-2>
									预设字符组：
								</div>
								<div grid grid-cols-2 md:grid-cols-4 gap-2>
									<div
										v-for="(
											symbols, key
										) in PRESET_SYMBOL_GROUPS"
										:key="key"
										@click="addSymbols(symbols)"
										class="cursor-pointer p-2 border border-gray-200 rounded hover:bg-gray-50 text-center text-sm"
										:title="`添加: ${symbols}`">
										<div font-mono text-xs>
											{{ symbols }}
										</div>
										<div text-xs text-gray-500 mt-1>
											{{ getSymbolGroupName(key) }}
										</div>
									</div>
								</div>
							</div>

							<!-- 自定义特殊字符 -->
							<div>
								<div text-sm text-gray-600 mb-2>
									自定义特殊字符：
								</div>
								<input
									v-model="passwordOptions.customSymbols"
									type="text"
									placeholder="输入您想要使用的特殊字符，如: !@#$%^&*()"
									class="w-full p-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
									maxlength="100" />
								<div text-xs text-gray-500 mt-1>
									当前字符集：{{
										passwordOptions.customSymbols ||
										'使用默认字符集'
									}}
								</div>
							</div>

							<!-- 快速操作 -->
							<div flex gap-2>
								<c-button
									size="small"
									@click="clearCustomSymbols"
									type="default">
									清空自定义
								</c-button>
								<c-button
									size="small"
									@click="useDefaultSymbols"
									type="default">
									使用默认字符集
								</c-button>
							</div>
						</div>
					</div>

					<!-- 排除选项 -->
					<div>
						<c-label>排除选项</c-label>
						<div grid grid-cols-1 md:grid-cols-2 gap-3 mt-2>
							<label flex items-center gap-2 cursor-pointer>
								<input
									v-model="passwordOptions.excludeSimilar"
									type="checkbox"
									class="rounded" />
								<span text-sm>排除相似字符 (il1Lo0O)</span>
							</label>
							<label flex items-center gap-2 cursor-pointer>
								<input
									v-model="passwordOptions.excludeAmbiguous"
									type="checkbox"
									class="rounded" />
								<span text-sm>
									排除易混淆字符 ({[]}()/\'"`~)
								</span>
							</label>
						</div>
					</div>

					<!-- 字符集信息 -->
					<div p-3 bg-blue-50 border border-blue-200 rounded text-sm>
						<div space-y-2>
							<div flex items-center gap-2>
								<span>ℹ️</span>
								<span text-blue-700>
									当前字符集大小：
									<strong>{{ charsetSize }}</strong>
									个字符
								</span>
							</div>
							<div
								v-if="
									passwordOptions.includeSymbols &&
									passwordOptions.customSymbols.trim()
								"
								text-xs
								text-blue-600>
								特殊字符：{{ passwordOptions.customSymbols }}
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- 密码安全建议 -->
			<div>
				<h3 text-lg font-semibold mb-4>密码安全建议</h3>
				<div space-y-2>
					<div
						v-for="suggestion in suggestions"
						:key="suggestion"
						flex
						items-center
						gap-2
						p-2
						bg-gray-50
						rounded>
						<span text-green-600>✓</span>
						<span text-sm text-gray-700>{{ suggestion }}</span>
					</div>
				</div>
			</div>
		</div>
	</c-card>
</template> 